const ble = require('../../utils/ble.js')
const util = require('../../utils/util.js')
const radio = require('../../utils/tef6686/radio.js')
const driver = require('../../utils/tef6686/driver.js')
const tuner = require('../../utils/tef6686/tuner.js')
const app = getApp()
//
const defaultStations = util.generateArray(8700, 10800, 10)
const defaultVolumes = util.generateArray(-60, 24, 1)
const defaultMutes = ['静音', '非静音']
Page({
  data: {
    find: false,
    connected: false,
    scan: false,
    value: [0, 60, 1],
    stations: defaultStations,
    displayStations: defaultStations.map(o => o / 100),
    favorite: false,
    favorites: [],
    volumes: defaultVolumes,
    mutes: defaultMutes,
    command: '',
    msgs: [],
  },
  bindChange(e) {
    const [stationIndex,volumeIndex,muteIndex]=e.detail.value
    const old = this.data.value
    if (stationIndex != old[0]) this.tuneToIndex(stationIndex)
    if (volumeIndex != old[1]) this.volumeToIndex(volumeIndex)
    if (muteIndex != old[2]) this.muteToIndex(muteIndex)
  },
  onFavorite() {
    const [stationIndex] = this.data.value
    const favorites = this.data.favorites
    const index = favorites.findIndex(o => o == stationIndex)
    if (index > -1) {
      favorites.splice(index, 1)
    } else {
      favorites.push(stationIndex)
    }
    this.setAndStoreFavorites(favorites.sort((a, b) => a - b))
  },
  onStation(e) {
    const { currentTarget: { dataset: { index } } } = e
    this.tuneToIndex(index)
  },
  tuneToIndex(stationIndex) {
    const value=this.data.value.slice(0)
    const station = defaultStations[stationIndex]
    radio.setFrequency(station)
    value[0]=stationIndex
    const favorites=this.data.favorites
    const favorite=favorites.includes(stationIndex)
    this.setData({favorite})
    this.setAndStoreValue(value)
  },
  volumeToIndex(volumeIndex) {
    const value=this.data.value.slice(0)
    const volume = defaultVolumes[volumeIndex]
    radio.setVolume(volume)
    value[1]=volumeIndex
    this.setAndStoreValue(value)
  },
  muteToIndex(muteIndex) {
    const value=this.data.value.slice(0)
    muteIndex == 0 ? radio.setMute() : radio.setUnMute()
    value[2]=muteIndex
    this.setAndStoreValue(value)
  },
  onScanDevice() {
    ble.found()
  },
  onConnectDevice() {
    ble.connect(!this.data.connected)
  },
  onCloseDevice() {
    ble.connect(false)
  },
  onClearMsgs() {
    this.setData({ msgs: [] })
  },
  onExecCommand() {
    const command = this.data.command
    const parse = (command, type) => {
      try {
        return JSON.parse(command.replace(type, '').replace(/，/g, ','))
      } catch (e) {
        return []
      }
    }
    if (command.includes('get')) {
      const args = parse(command, 'get')
      driver.devTEF668x_Get_Cmd(...args)
    } else {
      const args = parse(command, 'set')
      driver.devTEF668x_Set_Cmd(...args)
    }
    this.setData({
      command: ''
    })
  },
  setAndStoreFavorites(favorites) {
    const [stationIndex]=this.data.value
    const favorite=favorites.includes(stationIndex)
    this.setData({ favorite,favorites })
    return wx.setStorage({
      key: "favorites",
      data: favorites
    })
  },
  loadFavorites() {
    return new Promise((resolve)=>{
      wx.getStorage({ key: 'favorites' }).then(res => {
        this.setData({ favorites: res.data })
        resolve()
      }).catch(() => {
        this.setData({ favorites: [] })
        resolve()
      })
    })
  },
  setAndStoreValue(value){
    this.setData({value})
    return wx.setStorage({
      key: "value",
      data: value
    })
  },
  loadValue() {
    return new Promise((resolve)=>{
      const fn = (value) => {
        const [stationIndex, volumeIndex, muteIndex] = value
        this.tuneToIndex(stationIndex)
        this.volumeToIndex(volumeIndex)
        this.muteToIndex(muteIndex)
      }
      wx.getStorage({ key: 'value' }).then(res => {
        const value = res.data
        fn(value)
        this.setData({ value })
        resolve()
      }).catch(() => {
        const value = [0, 60, 1]
        fn(value)
        this.setData({ value })
        resolve()
      })
    })
  },
  appendMsg(event, list) {
    const msgs = this.data.msgs.slice(0, 100)
    msgs.unshift(`${event}-[${list.join(',')}]`)
    this.setData({ msgs })
  },
  async onScan() {
    this.setData({ scan: !this.data.scan })
    if (!this.data.scan) return
    const favorites = []
    this.setData({ favorites })
    const append = (stationIndex) => {
      favorites.push(stationIndex)
      this.setAndStoreFavorites(favorites)
    }
    for (let stationIndex = 0; stationIndex < defaultStations.length; stationIndex++) {
      if (!this.data.scan) return
      await this.tuneToIndex(stationIndex)
      if (await radio.checkStation()) {
        append(stationIndex)
        await tuner.waitMs(1000)
        continue;
      }
      await tuner.waitMs(5)
    }
    this.setData({ scan: false })
  },
  async onLoad() {
    await this.loadFavorites()
    await ble.authorize()
    await ble.open()
    await ble.listen()
    ble.on('found', find => {
      this.setData({ find })
    })
    ble.on('connect', async (connected) => {
      if (connected) {
        //ble
        await ble.getServices()
        await ble.getCharacteristics()
        await ble.notify()
        //radio
        await radio.init()
        await radio.powerOn()
        //
        await this.loadValue()
      } else {
        await ble.found()
      }
      this.setData({ connected })
    })
    ble.on('read', list => {
      this.appendMsg('read', list)
    })
    ble.on('write', list => {
      this.appendMsg('write', list)
    })
    ble.on('notify', list => {
      this.appendMsg('notify', list)
    })
  },
  onUnload() {
    ble.close()
  },
})